package com.tange.ai.iot.client.gnssa.utils.ble;

import static com.clj.fastble.data.BleScanState.STATE_SCANNING;

import android.content.Context;
import android.os.Handler;
import android.text.TextUtils;

import com.clj.fastble.BleManager;
import com.clj.fastble.callback.BleScanCallback;
import com.clj.fastble.data.BleDevice;
import com.clj.fastble.scan.BleScanRuleConfig;
import com.tange.ai.iot.client.gnssa.bean.BleSLDevice;
import com.tange.ai.iot.client.gnssa.utils.HexUtil;
import com.tange.ai.iot.client.gnssa.utils.LogUtil;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;


public class BleScan {
    private volatile static BleScan mVcooLink = null;
    private Context mContext;
    private Timer timer;
    public ArrayList<BleSLDevice> bleDeviceList = new ArrayList<>();
    private String BLETAG = "Ble Config-";
    private boolean isCancelScan = false;

    private List<BleSLDevice> bindSuccessBleDeviceList = new ArrayList<>();
    private ArrayList<VcooBleScanListenner> mListeners = new ArrayList<>();

    private BleScan() {
    }

    public static BleScan getInstance() {
        if (mVcooLink == null) {
            synchronized (BleScan.class) {
                if (mVcooLink == null) {
                    mVcooLink = new BleScan();
                }
            }
        }
        return mVcooLink;
    }

    public void init(Context context) {
        mContext = context;
    }

    public void startScanBle() {
        if (timer == null) {
            timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    BleScanRuleConfig config = new BleScanRuleConfig.Builder()
                            .setScanTimeOut(10 * 1000)
                            .build();
                    BleManager.getInstance().initScanRule(config);
                    if ((BleManager.getInstance().getScanSate() == STATE_SCANNING)) {
                        return;
                    }
                    BleManager.getInstance().scan(bleScanCallBack);
                }
            }, 0, 11 * 1000);
        }
    }

    private BleScanCallback bleScanCallBack = new BleScanCallback() {
        @Override
        public void onScanFinished(List<BleDevice> scanResultList) {
            try {
                if (isCancelScan) {
                    LogUtil.e(BLETAG + "============= 手动结束蓝牙扫描 ==============");
                    isCancelScan = false;
                    return;
                }
                if (scanResultList.size() == 0) {
                    return;
                }

                LogUtil.e(BLETAG + "============= 蓝牙扫描结束 ==============");
                bleDeviceList.clear();

                Iterator<BleDevice> iterator = scanResultList.iterator();
                while (iterator.hasNext()) {
                    BleDevice ble = iterator.next();
                    if (!TextUtils.isEmpty(ble.getName())
                            && (ble.getName().contains("G20"))
                    ) {
                        BleSLDevice BleSLDevice = new BleSLDevice();
                        BleSLDevice.bleDevice = ble;
                        bleDeviceList.add(BleSLDevice);
                    }
                }
//            for (BleDevice ble : scanResultList) {
//                if (!TextUtils.isEmpty(ble.getName())
//                        && (ble.getName().toUpperCase().contains("VCOO-") || ble.getName().contains("Hi-"))
//                ) {
//                    BleSLDevice BleSLDevice = new BleSLDevice();
//                    BleSLDevice.bleDevice = ble;
//                    bleDeviceList.add(BleSLDevice);
//                }
//            }

                checkBleDeviceV2();
                checkVcooDeviceWithBleDeviceV2();
                Collections.sort(bleDeviceList, new Comparator<BleSLDevice>() {
                    @Override
                    public int compare(BleSLDevice o1, BleSLDevice o2) {
                        return o2.bleDevice.getRssi() - o1.bleDevice.getRssi();
                    }
                });
                if (mListeners.size() > 0) {
                    for (VcooBleScanListenner mListener : mListeners) {
                        mListener.onScanFinished(scanResultList);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                LogUtil.e(e.getMessage());
            }
        }

        @Override
        public void onScanStarted(boolean success) {
            if (mListeners.size() > 0) {
                for (VcooBleScanListenner mListener : mListeners) {
                    mListener.onScanStarted(success);
                }
            }
            if (!success) {
                LogUtil.e(BLETAG + "=============  开启蓝牙扫描 失败  ==============");
            } else {
                LogUtil.e(BLETAG + "============= 开启蓝牙扫描成功 ==============");
            }
        }

        @Override
        public void onScanning(BleDevice bleDevice) {
            try {
                if (TextUtils.isEmpty(bleDevice.getName())) {
                    return;
                }

                boolean isInclude = false;
                for (BleSLDevice device : bleDeviceList) {
                    if (device.bleDevice.getMac().equals(bleDevice.getMac())) {
                        device.bleDevice = bleDevice;
                        isInclude = true;
                        break;
                    }
                }

                if (!isInclude) {
                    if (!TextUtils.isEmpty(bleDevice.getName())
                            && (bleDevice.getName().contains("G20"))
                    ) {
                        BleSLDevice BleSLDevice = new BleSLDevice();
                        BleSLDevice.bleDevice = bleDevice;
                        bleDeviceList.add(BleSLDevice);
                    }
                }
                checkBleDeviceV2();
                checkVcooDeviceWithBleDeviceV2();
                LogUtil.e(BLETAG + bleDevice.getMac() + "--" + bleDevice.getName() + ":" + bleDevice.getRssi());
                Collections.sort(bleDeviceList, new Comparator<BleSLDevice>() {
                    @Override
                    public int compare(BleSLDevice o1, BleSLDevice o2) {
                        return o2.bleDevice.getRssi() - o1.bleDevice.getRssi();
                    }
                });
                if (mListeners.size() > 0) {
                    for (VcooBleScanListenner mListener : mListeners) {
                        mListener.onScanning(bleDevice);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                LogUtil.e(e.getMessage());
            }
        }
    };

    /*
     * 基本不建议使用
     * */
    public void restartScan() {
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
        bleDeviceList.clear();
        if ((BleManager.getInstance().getScanSate() == STATE_SCANNING)) {
            BleManager.getInstance().cancelScan();
        }
        isCancelScan = true;
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                startScanBle();
            }
        }, 200);
    }

    public void addBindSuccessDevice(BleSLDevice device) {
        bindSuccessBleDeviceList.add(device);
        checkVcooDeviceWithBleDeviceV2();
    }

    public void checkVcooDeviceWithBleDeviceV2() {
        for (int i = 0; i < bindSuccessBleDeviceList.size(); i++) {
            if (System.currentTimeMillis() - bindSuccessBleDeviceList.get(i).bindSuccesTime > 10 * 1000) {
                //超过10s的  就删了他了
                bindSuccessBleDeviceList.remove(i);
                i--;
                continue;
            }

            Iterator<BleSLDevice> iterator = bleDeviceList.iterator();
            while (iterator.hasNext()) {
                BleSLDevice device = iterator.next();
                if (bindSuccessBleDeviceList.get(i).wifiMac.equals(device.wifiMac)) {
                    LogUtil.e(BLETAG + device.wifiMac + "已存在设备列表中，排除出去");
                    iterator.remove();
                }
            }
        }
    }

    private void checkBleDeviceV2() {
        Iterator<BleSLDevice> iterator = bleDeviceList.iterator();
        while (iterator.hasNext()) {
            BleSLDevice device = iterator.next();
            LogUtil.e(BLETAG + "扫描到:" + device.bleDevice.getName());
            if (device.bleDevice.getRssi() >= -50) {
                //信号最强
                device.level = 3;
            } else if (device.bleDevice.getRssi() <= -51 && device.bleDevice.getRssi() >= -65) {
                //信号中等
                device.level = 2;
            } else if (device.bleDevice.getRssi() <= -66 && device.bleDevice.getRssi() >= -80) {
                //信号弱
                device.level = 1;
            } else if (device.bleDevice.getRssi() <= -81) {
                device.level = 1;
                //信号极差删除
                LogUtil.e(BLETAG + device.bleDevice.getName() + "信号太弱，排除出去");
//                iterator.remove();
//                continue;
            }

            byte[] bleBytes = device.bleDevice.getScanRecord();
            ArrayList<byte[]> bytesList = new ArrayList<>();

            for (int i = 0; i < bleBytes.length; ) {
                int length = bleBytes[i];
                byte[] bytes = new byte[length + 1];
                System.arraycopy(bleBytes, i, bytes, 0, bytes.length);
                if (bytes.length == 1 && bytes[0] == 0) {
                    break;
                }
                bytesList.add(bytes);
                i = i + bytes.length;
            }
            byte[] uuidBytes = null;
            byte[] pidMacBytes = null;
            for (byte[] bean : bytesList) {
                if (Byte.toUnsignedInt(bean[1]) == 0xFF) {
                    uuidBytes = new byte[bean.length - 2];
                    System.arraycopy(bean, 2, uuidBytes, 0, uuidBytes.length);
                }
                if (Byte.toUnsignedInt(bean[1])== 0x16) {
                    pidMacBytes = new byte[bean.length - 2];
                    System.arraycopy(bean, 2, pidMacBytes, 0, pidMacBytes.length);
                }
            }
            if (uuidBytes == null || pidMacBytes == null) {
                continue;
            }

            if (device.bleDevice.getName().contains("G20")) {
                //platform 平台
                device.platform=uuidBytes[0];
                device.verison=uuidBytes[1];
                device.venderId=uuidBytes[2];

                //UUID
                byte[] tangeUUID = new byte[12];
                System.arraycopy(uuidBytes, 3, tangeUUID, 0, tangeUUID.length);
                device.tangeUUID=new String(tangeUUID);


                //pid
                byte[] pid = new byte[6];
                System.arraycopy(pidMacBytes, 2, pid, 0, pid.length);
                String pidStr = HexUtil.bytesToHexString(pid).toUpperCase();
                device.pId = pidStr;

                //wifi mac
                byte[] wifiMac = new byte[6];
                System.arraycopy(pidMacBytes, 2+6, wifiMac, 0, wifiMac.length);
                String wifiMacStr = HexUtil.bytesToHexString(wifiMac).toUpperCase();
                device.wifiMac = wifiMacStr;
            }

            if (TextUtils.isEmpty(device.wifiMac)) {
                iterator.remove();
                continue;
            }
        }
    }

    public void cancelVcooBleScan() {
        LogUtil.e(BLETAG + "============= 手动结束蓝牙扫描 ==============");
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
        if ((BleManager.getInstance().getScanSate() == STATE_SCANNING)) {
            BleManager.getInstance().cancelScan();
        }
    }

    public void startScanBleOnce(int second) {
        bleDeviceList.clear();
        BleScanRuleConfig config = new BleScanRuleConfig.Builder()
                .setScanTimeOut(second * 1000)
                .build();
        BleManager.getInstance().initScanRule(config);
        if ((BleManager.getInstance().getScanSate() == STATE_SCANNING)) {
            return;
        }
        BleManager.getInstance().scan(bleScanCallBack);
    }

    public void setVcooBleScanListener(VcooBleScanListenner listener) {
        mListeners.add(listener);
    }

    public void removeVcooBleScanListener(VcooBleScanListenner listener) {
        mListeners.remove(listener);
    }

    public void removeAllVcooBleScanListener() {
        mListeners.clear();
    }

    public void destory() {
        mListeners.clear();
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
        if ((BleManager.getInstance().getScanSate() == STATE_SCANNING)) {
            BleManager.getInstance().cancelScan();
        }
    }

    public interface VcooBleScanListenner {
        void onScanStarted(boolean success);

        void onScanning(BleDevice bleDevice);

        void onScanFinished(List<BleDevice> scanResultList);
    }


    @Deprecated
    public void checkVcooDeviceWithBleDevice() {
        for (int i = 0; i < bindSuccessBleDeviceList.size(); i++) {
            if (System.currentTimeMillis() - bindSuccessBleDeviceList.get(i).bindSuccesTime > 10 * 1000) {
                //超过10s的  就删了他了
                bindSuccessBleDeviceList.remove(i);
                i--;
                continue;
            }
            for (int z = 0; z < bleDeviceList.size(); z++) {
                if (bindSuccessBleDeviceList.get(i).wifiMac.equals(bleDeviceList.get(z).wifiMac)) {
                    LogUtil.e(BLETAG + bleDeviceList.get(z).wifiMac + "已存在设备列表中，排除出去");
                    bleDeviceList.remove(z);
                    z--;
                }
            }

        }
    }
}
